﻿using System;
using System.Collections.Generic;
using System.Linq;
using Loki.Engine;
using Luna.Data.Security;
using Luna.Model.Security;
using NUnit.Framework;

namespace Luna.Data.Tests
{
    [TestFixture]
    public class UserTest : AssertionHelper
    {
        public IUserData User1 { get; set; }
        public IUserData User2 { get; set; }
        public IUserData User3 { get; set; }

        private bool AreSame(IUserData P_User1, IUserData P_User2)
        {
            bool b = true;
            b &= P_User1.PK == P_User2.PK;
            b &= P_User1.Hash == P_User2.Hash;
            b &= P_User1.Login == P_User2.Login;
            b &= P_User1.Name == P_User2.Name;
            b &= P_User1.Surname == P_User2.Surname;
            return b;
        }

        public ISecurityDataProvider Data { get; set; }

        private IUserData Create(string P_Name)
        {
            IUserData L_Return = Data.Create<IUserData>();
            L_Return.PK = Guid.NewGuid();
            L_Return.Login = P_Name + "Login";
            L_Return.Name = P_Name + "Name";
            L_Return.Surname = P_Name + "Surname";
            return L_Return;
        }

        [SetUp]
        public void SetUp()
        {
            Data = ContextHelper.GetDataModel<LunaDataModel>().Security;

            User1 = Create("User1");
            User2 = Create("User2");
            User3 = Create("User3");

            User1.Hash = GetHash("User1_Password");
            User2.Hash = GetHash("User2_Password");
            User3.Hash = GetHash("User3_Password");

            CleanTable();
        }

        private string GetHash(string P_Password)
        {
            User L_User = new User();
            L_User.SetPassword(P_Password);
            return L_User.Hash;
        }

        private void CleanTable()
        {
            IEnumerable<IUserData> L_Users = Data.GetAllUsers();
            foreach (var L_User in L_Users)
            {
                Data.DeleteUser(L_User.PK);
            }
        }

        [Test]
        public void TestInsertAndGet()
        {
            Data.SaveUser(User1);
            IUserData L_User = Data.GetUser(User1.PK);
            Expect(AreSame(User1, L_User), Is.True);
        }

        [Test]
        public void TestUpdateAndGet()
        {
            Data.SaveUser(User1);
            User1.Login = "User1_Login_Modified";
            Data.SaveUser(User1);

            IUserData L_User = Data.GetUser(User1.PK);
            Expect(AreSame(User1, L_User), Is.True);

            Expect(L_User.Login, Is.EqualTo("User1_Login_Modified"));
        }

        [Test]
        public void TestInsertAndGetAll()
        {
            Data.SaveUser(User1);
            Data.SaveUser(User2);
            Data.SaveUser(User3);

            int L_Count = Data.GetAllUsers().Count();
            Expect(L_Count, Is.EqualTo(3));
        }

        [Test]
        public void TestInsertAndDelete()
        {
            Data.SaveUser(User1);
            Data.SaveUser(User2);
            Data.DeleteUser(User1.PK);

            int L_Count = Data.GetAllUsers().Count();
            Expect(L_Count, Is.EqualTo(1));
            IUserData L_User = Data.GetUser(User1.PK);
            Expect(L_User, Is.Null);

        }
    }
}
